package realtime;

import java.awt.Cursor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;

import document.Document;

import messagepasser.*;

public class SendDocumentState extends TimerTask {
	private Document doc;
	private Timer myTimer;
	private String consistentState;
	private boolean noChange = true;
	private boolean sentMulticast = false;
	private int waitTime = 10;

	
	public SendDocumentState(Document d, Timer t, String content) {
		doc = d;
		myTimer = t;
		consistentState = content;
	}
	
	public void run() {
		if(doc.getDocId()==1000){
		
			return;
		}
		diff_match_patch dmp = new diff_match_patch();
		String currText = doc.contentBox.getText();
		String dest = getOnlineUsers();
		
		// no online users;
		if (dest.length() == 0) {
			return;
		}
		
		noChange = currText.equals(consistentState);
		
		// if there was change in the document since last time checked
		if (noChange == false) {
			LinkedList<diff_match_patch.Diff> diff = dmp.diff_main (consistentState, currText);
			dmp.diff_cleanupSemantic(diff);
			LinkedList<diff_match_patch.Patch> patchList = dmp.patch_make(consistentState, currText, diff);
			
			TimeStampedMessage m = new TimeStampedMessage(dest, doc.getMyPasser().getMyName(), "abc",
					"abc", patchList, false, true);
			m.setMsgType("SendDocumentChanges");
			m.getHeader().setId(doc.getDocId() + "");
			doc.getMyPasser().send(m);
			this.sentMulticast = false;
		}
		else {
			//if (this.sentMulticast == false) {
				waitTime--;
				if (waitTime == 0) {
					//if there was no change in the document, then send the entire text to verify the consistency
					TimeStampedMessage m = new TimeStampedMessage(dest, doc.getMyPasser().getMyName(), "abc",
							"abc", currText, false, true);
					m.setMsgType("MulticastDocumentState");
					m.getHeader().setId(doc.getDocId() + "");
					doc.getMyPasser().send(m);
					this.sentMulticast = true;
					waitTime = 10;
				}
				 
			//}	
		}
		
		Message data = doc.getMyPasser().receive();
		
		if (data != null) {
			
			// check if entire document was sent to check the consistency
			
			if (data.getMsgType().equals("MulticastDocumentState")) {
				String recvText = (String)data.getPayload();
				if (noChange) {
					// check the priority
					int position = doc.contentBox.getCaretPosition();
					// found an inconsistent state
					if (doc.contentBox.getText().equals (recvText) == false) {
						if (doc.getMyPasser().getMyName().compareTo(data.getPhySender()) < 0) {
							JOptionPane popUp = new JOptionPane();
							popUp.showMessageDialog(null,
									"Found Conflict",
									"Conflict",
									JOptionPane.ERROR_MESSAGE);
							doc.contentBox.setText(recvText);
							consistentState = recvText;
						}
						else {
							consistentState = currText;
						}
					}
					// adjust the caret position
					try {
						if (position < doc.contentBox.getText().length()) {
							doc.contentBox.setCaretPosition(position);
						}	
					}catch (Exception e) {
						System.out.println ("DBUG : got error in setting position\n");
					}
				
				}
				else {
					consistentState = currText;
				}
				return;
			}
			
			LinkedList<diff_match_patch.Patch> patches = (LinkedList<diff_match_patch.Patch>) (data.getPayload());
			Object[] result = dmp.patch_apply(patches, currText);
			consistentState = (String)result[0];
			
			// adjust the user cursor position
			int position = doc.contentBox.getCaretPosition();
			doc.contentBox.setText((String)result[0]);
			if (position > doc.contentBox.getCaretPosition()) {
				try {
					doc.contentBox.setCaretPosition(position);
				}
				catch (Exception e) {}
			}
			
		}
		else {
			consistentState = currText; 
		}
		
	}

	private String getOnlineUsers() {
		
		String olUsers = "";
		
		for (int i = 0; i < doc.getUsers().size(); i++) {
			if (doc.getUsers().get(i).isOnlinestatus()) {
				olUsers = olUsers + doc.getUsers().get(i).getUsername();
			}
			if (i < doc.getUsers().size() - 1) {
				if (doc.getUsers().get(i).isOnlinestatus()) {
					olUsers = olUsers + ",";
				}
			}
			
		}
		return olUsers;
	}
}



